package ar.edu.utn.frgp.TPFinalBanco.action;

import java.math.BigDecimal;
import java.util.*;

import ar.edu.utn.frgp.TPFinalBanco.model.Cliente;
import ar.edu.utn.frgp.TPFinalBanco.model.Cuenta;
import ar.edu.utn.frgp.TPFinalBanco.model.Movimiento;
import ar.edu.utn.frgp.TPFinalBanco.model.OrigenDineroEnum;
import ar.edu.utn.frgp.TPFinalBanco.model.OrigenMovEnum;
import ar.edu.utn.frgp.TPFinalBanco.model.PagoPrestamo;
import ar.edu.utn.frgp.TPFinalBanco.model.Prestamo;
import ar.edu.utn.frgp.TPFinalBanco.model.TipoMovimientoEnum;
import ar.edu.utn.frgp.TPFinalBanco.service.impl.GestionCuentaServiceImpl;
import ar.edu.utn.frgp.TPFinalBanco.service.impl.GestionMovimientosServiceImpl;
import ar.edu.utn.frgp.TPFinalBanco.service.impl.GestionPagoPrestamoServiceImpl;
import ar.edu.utn.frgp.TPFinalBanco.service.impl.GestionPrestamoServiceImpl;

import com.opensymphony.xwork2.ActionContext;

public class PagarCuotaPrestamoAction extends BaseAction{


	private static final long serialVersionUID = -8241626536031542868L;
	private Map<String, Object> session;
	private Date fecha;
	private Boolean formaEfectivo;
	private Boolean loguio;
	private Integer nroCuenta;
	private BigDecimal monto;
	private Cliente cliente;
	private Prestamo prestamo;
	private Date ahora;
	private Boolean tiene;
	
	public String execute() throws Exception{
		
			setLoguio(true);
		
			// paso la session.
			setSession(ActionContext.getContext().getSession());
			setCliente((Cliente) session.get("cliente"));
			setPrestamo((Prestamo) session.get("prestamo"));
			//obtengo la fecha del sistema
			setAhora(new Date());
						
			//verifico si el cliente tiene cuentas
			if(((Cliente) session.get("cliente")).getCantCuentas() > 0){
				setTiene(true);
			}
			
			PagoPrestamo pago=new PagoPrestamo();	
			pago.setFecha(fecha);
			pago.setDni(cliente.getDni());
			pago.setIdPrestamo(prestamo.getIdPrestamo());
			
			//Verifico si el pago es con debito o efectivo
			if(getFormaEfectivo()){
			//en efectivo
				pago.setOrigen(OrigenDineroEnum.E);
			
				//guardo el pago
				GestionPagoPrestamoServiceImpl pagoPrestamoService= (GestionPagoPrestamoServiceImpl) getContext().getBean("gestionPagoPrestamoService");
				pagoPrestamoService.savePagoPrestamo(pago);
				
				if((Boolean) session.get("ultima")){
					//marco a pagado el prestamo
					prestamo.setEstado(true);
					GestionPrestamoServiceImpl prestamoService= (GestionPrestamoServiceImpl) getContext().getBean("gestionPrestamoService");
					prestamoService.updatePrestamo(prestamo);
					}
				
				return SUCCESS;
			
			}else{
			//en debito	
				pago.setNroCuenta(nroCuenta);
				pago.setOrigen(OrigenDineroEnum.C);	
				//chequeo que la cuenta tenga plata traigo la cuenta
				GestionCuentaServiceImpl cuentaService = (GestionCuentaServiceImpl) getContext()
						.getBean("gestionCuentasService");
				Cuenta cuenta = cuentaService
						.getCuenta(getNroCuenta());
				
				if ((cuenta.getSaldo().add(cuenta.getDescubierto())).compareTo(monto) >= 0) {

					BigDecimal saldoActual = cuenta.getSaldo().subtract(monto);

					// Genero el movimiento y lo agrego en la BD
					Movimiento movimiento = new Movimiento(
							cuenta, new Date(),
							TipoMovimientoEnum.E, OrigenMovEnum.PR, saldoActual,
							monto);
					GestionMovimientosServiceImpl movimientosService = (GestionMovimientosServiceImpl) getContext()
							.getBean("gestionMovimientosService");
					movimientosService.createMovimiento(movimiento);

					// Actualizo el saldo de la cuenta y lo guardo en la BD
					cuenta.setSaldo(saldoActual);
					cuentaService.updateCuenta(cuenta);

					// Actualizo la cuenta en la sesión
					List<Cuenta> cuentas = cliente.getCuentas();

					for (Cuenta cuentaCliente : cuentas) {
						if (cuentaCliente.getNroCuenta().equals(cuenta.getNroCuenta())) {
							cuentaCliente.setSaldo(saldoActual);
						}
					}

					cliente.setCuentas(cuentas);
					ActionContext.getContext().getSession().put("cliente", cliente);
					
					//guardo el pago
					GestionPagoPrestamoServiceImpl pagoPrestamoService= (GestionPagoPrestamoServiceImpl) getContext().getBean("gestionPagoPrestamoService");
					pagoPrestamoService.savePagoPrestamo(pago);
					
					if((Boolean) session.get("ultima")){
						//marco a pagado el prestamo
						prestamo.setEstado(true);
						GestionPrestamoServiceImpl prestamoService= (GestionPrestamoServiceImpl) getContext().getBean("gestionPrestamoService");
						prestamoService.updatePrestamo(prestamo);
					}
					
					return SUCCESS;
					
				}else{

					//Salgo con el error de Saldo insuficiente
					addActionError("¡¡Saldo Insuficiente en la cuenta seleccionada!!");
					return ERROR;
					
				}	

				
			}			

	
	}

	public Map<String, Object> getSession() {
		return session;
	}

	public void setSession(Map<String, Object> session) {
		this.session = session;
	}

	public Cliente getCliente() {
		return cliente;
	}

	public void setCliente(Cliente cliente) {
		this.cliente = cliente;
	}

	public Date getFecha() {
		return fecha;
	}

	public void setFecha(Date fecha) {
		this.fecha = fecha;
	}

	public Boolean getFormaEfectivo() {
		return formaEfectivo;
	}

	public void setFormaEfectivo(Boolean formaEfectivo) {
		this.formaEfectivo = formaEfectivo;
	}

	public Boolean getLoguio() {
		return loguio;
	}

	public void setLoguio(Boolean loguio) {
		this.loguio = loguio;
	}

	public Integer getNroCuenta() {
		return nroCuenta;
	}

	public void setNroCuenta(Integer nroCuenta) {
		this.nroCuenta = nroCuenta;
	}

	public BigDecimal getMonto() {
		return monto;
	}

	public void setMonto(BigDecimal monto) {
		this.monto = monto;
	}

	public Prestamo getPrestamo() {
		return prestamo;
	}

	public void setPrestamo(Prestamo prestamo) {
		this.prestamo = prestamo;
	}

	public Boolean getTiene() {
		return tiene;
	}

	public void setTiene(Boolean tiene) {
		this.tiene = tiene;
	}

	public Date getAhora() {
		return ahora;
	}

	public void setAhora(Date ahora) {
		this.ahora = ahora;
	}


}
